#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

ssize_t my_readv(int fd, const struct iovec *iov, int iovcnt){
    off_t currentSeek;
    ssize_t allReded = 0, readed = 0;

    currentSeek = lseek(fd, 0, SEEK_CUR);
    if (currentSeek == -1){
        printf("Error get current seek fd %d - %s\n", fd, strerror(errno));
        return -1;        
    }
    for(int i = 0 ; i < iovcnt; i++, readed = 0){
        readed = read(fd, iov[i].iov_base, iov[i].iov_len);
        if(readed == -1){
            printf("Error read fd %d - %s\n", fd, strerror(errno));
            return -1;
        }
        allReded += readed;
    }

    if(lseek(fd, currentSeek, SEEK_SET) == -1){
        printf("Error revert seek fd %d - %s\n", fd, strerror(errno));
        return -1;            
    }
    return allReded;

}

ssize_t my_writev(int fd, const struct iovec *iov, int iovcnt){
    off_t currentSeek;
    ssize_t allWrited = 0, writed = 0;

    currentSeek = lseek(fd, 0, SEEK_CUR);
    if (currentSeek == -1){
        printf("Error get current seek fd %d - %s\n", fd, strerror(errno));
        return -1;        
    }
    for(int i = 0 ; i < iovcnt; i++, writed = 0){
        writed = write(fd, iov[i].iov_base, iov[i].iov_len);
        if(writed == -1){
            printf("Error write fd %d - %s\n", fd, strerror(errno));
            return -1;
        }
        allWrited += writed;
    }

    if(lseek(fd, currentSeek, SEEK_SET) == -1){
        printf("Error revert seek fd %d - %s\n", fd, strerror(errno));
        return -1;            
    }
    return allWrited;
}

int main(){
    int fd;
    char *filePtr = "file5_7.txt";
    int buf1 = 2223;
    char buf2[] = "Hello form buffer2!";
    struct iovec iov[2];
    struct iovec iov1, iov2;

    iov1.iov_base = &buf1;
    iov1.iov_len = sizeof(buf1);
    iov2.iov_base = buf2;
    iov2.iov_len = strlen(buf2);
    iov[0] = iov1;
    iov[1] = iov2;

    fd = open(filePtr, O_CREAT | O_RDWR, S_IWUSR | S_IRUSR | S_IROTH);
    if (fd == -1){
        printf("Error open file %s %s\n", filePtr, strerror(errno));
        exit(EXIT_FAILURE);
    }
    
    printf("Must be writed %ld, writed in file %s, %ld\n", iov1.iov_len + iov2.iov_len, filePtr, my_writev(fd, iov, 2));
    //printf("Must be writed %ld, writedv in file %s, %ld\n", iov1.iov_len + iov2.iov_len, filePtr, writev(fd, iov, 2));
    buf1 = 0;
    buf2[0] = 'a';
    buf2[1] = 'b';
    printf("Data before read bu1 = %d buf2 = %s\n", buf1, buf2);
    printf("Readed from file %s, %ld\n", filePtr, my_readv(fd, iov, 2));
    printf("Value buf1 = %d, buf2 = %s\n", *((int*) iov1.iov_base), (char *)(iov2.iov_base));


    if(close(fd) == -1){
        printf("Error close file %s %s\n", filePtr, strerror(errno));
        exit(EXIT_FAILURE);       
    }

}